---
title: Migration to v0.7
---

import { Callout } from "fumadocs-ui/components/callout";

This guide serves as a reference for users facing breaking changes during upgrade to v0.7. You do not need to read this guide to upgrade to v0.7.

All breaking changes in v0.7 are renames or removals of existing APIs. Therefore, all breaking changes should cause a Typescript error, so you can simply check for errors after upgrading.

### Component Property Types moved to `Component.Props`

Component property types are now neatly organized under the component itself.

```diff
-import { ThreadPrimitiveMessagesProps } from "@assistant-ui/react";
+import { ThreadPrimitive } from "@assistant-ui/react";

-type Props = ThreadPrimitiveMessagesProps;
+type Props = ThreadPrimitive.Messages.Props;
```

## Context API simplifications

### `useThreadContext`, `useMessageContext`, ... replaced with direct imports of stores

`useAssistantContext`, `useThreadContext`, `useMessageContext` and `useMessagePartContext` have been removed in favor of direct exports from `@assistant-ui/react`;

```diff
-const { useThread } = useThreadContext();

+import { useThread } from "@assistant-ui/react";
```

# Assistant Context API simplifications

### `useAssistantActions` replaced with `useAssistantRuntime`

`useAssistantActions` has been removed in favor of `useAssistantRuntime`.

```diff
-const switchToNewThread = useAssistantActions(a => a.switchToNewThread);
+const runtime = useAssistantRuntime();
+runtime.switchToNewThread();
```

### `switchToThread(null)` replaced with `switchToNewThread()`

```diff
-useThreadRuntime().switchToThread(null);
+useThreadRuntime().switchToNewThread();
```

### useSwtichToNewThread() moved to useAssistantRuntime().switchToNewThread()

```diff
-useSwitchToNewThread();
+const runtime = useAssistantRuntime()
+runtime.switchToNewThread();
```

### `runtime.subscribe` removed, `subscribeToMainThread` removed

Previously, you needed to subscribe to the runtime to receive updates whenever the main thread changed and resubscribe to the main thread whenever you switched to a new thread. The `runtime.thread` value now always refers to the current main thread, there is no need to subscribe to the runtime anymore.

## ThreadRuntime API simplifications

### `useAppendMessage` moved to `useThreadRuntime().append()`

```diff
-const append = useAppendMessage();
+const threadRuntime = useThreadRuntime();
-append("hello world");
+threadRuntime.append("hello world");
```

### `useThreadActions` replaced with `useThreadRuntime`

`useThreadActions` has been removed in favor of `useThreadRuntime`.

```diff
-const reload = useThreadActions(a => a.reload);
+const threadRuntime = useThreadRuntime();
+threadRuntime.reload();
```

### State values moved to `threadRuntime.getState()`

In order to make it clear that accessing the state only provides a snapshot of the current state and will not cause a re-render on changes, the state values of `useThreadRuntime` have been moved to `threadRuntime.getState()`.

```diff
-const isRunning = useThreadRuntime().isRunning; // anti-pattern, your code will not update on change
+const isRunning = useThread(t => t.isRunning);
```

### `useThreadStore` replaced with `useThreadRuntime().getState()`

`useThreadStore` has been removed in favor of `useThreadRuntime().getState()`.

### `threadRuntime.getBranches()` replaced with `useThreadRuntime().getMessageByIndex(idx).getState().branchNumber/Count`

The branch IDs are an internal implementation detail. The new Message Runtime API provides `branchNumber` and `branchCount` state fields that can be used instead.

### New Message Runtime API replaces several methods from `useThreadRuntime`

A few methods from `useThreadRuntime` have been moved to `useMessageRuntime()`.

- `threadRuntime.switchToBranch()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).switchToBranch()`.
- `threadRuntime.addToolResult()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).getMessagePartByToolCallId(toolCallId).addToolResult()`.
- `threadRuntime.speak()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).speak()`.
- `threadRuntime.submitFeedback()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).submitFeedback()`.
- `threadRuntime.getEditComposer()` has been removed in favor of `useThreadRuntime().getMessageById(id).getMessageByIndex(idx).composer`.
- `threadRuntime.beginEdit()` has been removed in favor of `useThreadRuntime().getMessageById(id).getMessageByIndex(idx).composer.beginEdit()`.

## Composer Runtime API simplifications

### Methods inside `useComposer` moved to `useComposerRuntime`

`useComposer()` used to provide several methods such as `setText`, `addAttachment`, `send`, `edit`, `cancel`, ...
These methods have been moved to `useComposerRuntime()`.

### `useComposerStore` replaced with `useComposerRuntime().getState()`

`useComposerStore` has been removed in favor of `useComposerRuntime().getState()`.

### `value` `setValue` replaced with `text` `setText`

```diff
-useComposer(c => c.value);
+useComposer(c => c.text);
```

### `focus`, `onFocus` methods removed

These methods have been removed.

## Message Context API simplifications

### Flattened context values `useMessage().message` -> `useMessage()`

`MessageState` is now itself a message, so you no longer need to access the nested `useMessage().message` field.

```diff
-useMessage(m => m.message.content);
+useMessage(m => m.content);
```

### `useMessageStore` replaced with `useMessageRuntime().getState()`

`useMessageStore` has been removed in favor of `useMessageRuntime().getState()`.

## Message part Context API simplifications

### Flattened context values `useMessagePart().part` -> `useMessagePart()`

`MessagePartState` is now itself a message part, so you no longer need to access the nested `useMessagePart().part` field.

```diff
-useMessagePart(c => c.part.type);
+useMessagePart(c => c.type);
```

This also applies to tool UI render functions:

```diff
 makeAssistantToolUI({
   ...
-  render: ({ part: { args } }) => <>{args}</>,
+  render: ({ args }) => <>{args}</>,
 });
```

## Attachment Context API simplifications

### Flattened context values `useAttachment().attachment` -> `useAttachment()`

`AttachmentState` is now itself an attachment, so you no longer need to access the nested `useAttachment().attachment` field.

```diff
-useAttachment(a => a.attachment.type);
+useAttachment(a => a.type);
```

## Roundtrips renamed to steps

`AssistantMessage.roundtrips` was renamed to `AssistantMessage.metadata.steps`.

Edge runtime's `maxToolRoundtrips` was replaced with `maxSteps` (which is `maxToolRoundtrips` + 1; if you had `maxToolRoundtrips` at 2, set `maxSteps` to 3).
